package mobweb.booktrack;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;

public class NetworkTask extends AsyncTask<String, Void, JSONObject> {
	private AsyncTaskCompleteListener<Book> callback;
	private Context context;
	
	public NetworkTask(Context context, AsyncTaskCompleteListener<Book> cb) {
		this.context = context;
		this.callback = cb;
	}

	@Override
	protected JSONObject doInBackground(String... url) {
		JSONObject json = null;
		
		if (isOnline()) {
			// Prepare a request object
		    HttpGet httpget = new HttpGet(url[0]);
			HttpParams httpParameters = new BasicHttpParams();
		    
			// The default value is zero, that means the timeout is not used. 
			int timeoutConnection = 3000;
			HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
			
			int timeoutSocket = 5000;
			HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
			
	
			HttpClient httpclient = new DefaultHttpClient(httpParameters);
			
		    // Accept JSON
		    httpget.addHeader("accept", "application/json");
		    // Execute the request
		    HttpResponse response;
		    try {
		        response = httpclient.execute(httpget);
		        // Get the response entity
		        HttpEntity entity = response.getEntity();
		        // If response entity is not null
		        if (entity != null) {
		            // get entity contents and convert it to string
		            InputStream instream = entity.getContent();
		            String result = convertStreamToString(instream);
		            // construct a JSON object with result
		            json=new JSONObject(result);
		            // Closing the input stream will trigger connection release
		            instream.close();
		        }
		    } catch (ClientProtocolException e) {
		        // TODO Auto-generated catch block
		        e.printStackTrace();
		    } catch (IOException e) {
		        // TODO Auto-generated catch block
		        e.printStackTrace();
		    } catch (JSONException e) {
		        // TODO Auto-generated catch block
		        e.printStackTrace();
		    }
		} else {
			json = new JSONObject();
			try {
				json.put("totalItems", "0");
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
		
	    // Return the json
	    return json;
	}
	
	@Override
	protected void onPostExecute(JSONObject jso) {
		Book book = new Book();
		
		try {
			if (jso.getInt("totalItems") > 0) {
	        	JSONObject items = jso.getJSONArray("items").getJSONObject(0);
	        	
	        	if (items.has("volumeInfo")) {
	        		JSONObject volumeInfo = items.getJSONObject("volumeInfo");
	        		
	        		if(volumeInfo.has("title")) {
                        book.setBookName(volumeInfo.getString("title"));
                    }
	        		
	        		if(volumeInfo.has("authors")) {
	        			book.setAuthor(convertArrayToString(volumeInfo.getJSONArray("authors")));
                    }
	        		
	        		if(volumeInfo.has("categories")) {
	        			book.setCategory(convertArrayToString(volumeInfo.getJSONArray("categories")));
                    }
	        		
	        		if(volumeInfo.has("description")) {
                        book.setDescription(volumeInfo.getString("description"));
                    }
	        		
	        		if(volumeInfo.has("industryIdentifiers")) { 
	        			JSONArray isbnArray = volumeInfo.getJSONArray("industryIdentifiers");
						
						for (int isbnCount=0;isbnCount<isbnArray.length();isbnCount++) {
					        JSONObject isbn=(JSONObject)isbnArray.get(isbnCount);
					      
					        if(isbn.getString(("type")).equals("ISBN_13")) {
					        	book.setISBN(isbn.getString("identifier"));
					        }
						}
                    }
	        		
		        	callback.onTaskComplete(book);
	        	} else {
	        		callback.onTaskComplete(null);
	        	}
			} else {
				callback.onTaskComplete(null);
			}
		} catch (JSONException e){
			callback.onTaskComplete(null);
		}
    }
	
	/*** Helper functions ***/
	
	/**
	 * 
	 * Checks if there is an internet connection
	 * 
	 * @return Boolean
	 */
	public boolean isOnline() {
	    ConnectivityManager connMgr = (ConnectivityManager) 
	            this.context.getSystemService(Context.CONNECTIVITY_SERVICE);
	    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
	    return (networkInfo != null && networkInfo.isConnected());
	}
	
	private static String convertStreamToString(InputStream instream) {
		BufferedReader buffer = new BufferedReader (new InputStreamReader(instream));
		String line = "", returnS="";
		try {
		    while ((line = buffer.readLine())!=null) {
		        returnS=returnS+line;
		    }
		} catch (IOException e) {
		    e.printStackTrace();
		}
		return returnS;
    }
	
	private static String convertArrayToString(JSONArray arr) throws JSONException {
		String result = "";
		result = result + arr.getString(0);
		
		for (int i = 1; i < arr.length(); i++){
		    result = result + ", " + arr.getString(i);
		}
		
		return result;
    }

}
